/**
 * 成员列表（成员管理）弹层-公共组件
 */

import React from 'react';
import PropTypes from 'prop-types';
import { TeamixAvatar } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import Member from '@alife/yunxiao-member';
import { getFeature } from 'utils/features';
import { navigateOpen } from 'utils/router';
import { getProjectMembers, getOrgMembers, customMemberSearchAll } from 'api';
import MemberList from 'components/memberList';
import intl from '../../locale';
import './index.scss';

const { ClusterAvatar } = TeamixAvatar;

export default class MemberTrigger extends React.PureComponent {
  static propTypes = {
    usersFilterAccess: PropTypes.number,
    onChange: PropTypes.func,
    value: PropTypes.array,
    needAvatar: PropTypes.bool,
    mode: PropTypes.string,
    defaultList: PropTypes.string,
    multiple: PropTypes.bool,
    pathResourceType: PropTypes.oneOf(['project', 'group']),
    pathResourceId: PropTypes.number,
    useExtraMember: PropTypes.oneOf(['project', 'approve']),
    useRecommendMember: PropTypes.bool,
    recommendList: PropTypes.array,
    useProjectMember: PropTypes.bool,
    followTrigger: PropTypes.bool,
    isInviteUrl: PropTypes.bool,
  };

  static defaultProps = {
    onChange: () => {},
    usersFilterAccess: 0,
    value: [],
    needAvatar: false,
    mode: 'edit',
    defaultList: '',
    multiple: false,
    pathResourceType: 'project',
    pathResourceId: null,
    useExtraMember: null,
    useRecommendMember: false,
    recommendList: [],
    useProjectMember: false,
    followTrigger: true,
  };

  constructor(props) {
    super(props);
    this.state = {
      isMemberOverlayVisible: false,
      extraMembers: [],
      // 点击邀请大的memberPanel
      memberSettingShow: false,
      orgMembers: [],
    };
  }

  UNSAFE_componentWillMount() {
    if (this.props.useExtraMember === 'project') {
      this.getDataSource();
    }
  }

  getDataSource = (callback) => {
    let { pathResourceId } = this.props;
    if (!pathResourceId) {
      pathResourceId = window.FORCE.pathResource.id;
    }
    if (!pathResourceId) {
      callback && callback();
      return false;
    }
    const { organization_id } = window.FORCE.organization;
    // orgMembers 用来控制列表下的邀请按钮显隐，既然vpc这里不显示，那这个接口不用去请求；
    const promise1 = getFeature('member.memberList.inviteBtn') ? getOrgMembers(organization_id) : Promise.resolve([]);
    const allPromise = Promise.all([
      promise1,
      getProjectMembers(pathResourceId),
    ]);
    allPromise
      .then((res) => {
        const [orgMembers, result] = res;
        result.shift();
        this.setState({
          extraMembers: result.filter((va) => va.access_level >= this.props.usersFilterAccess),
          orgMembers,
        });

        callback && callback();
      })
      .catch((err) => {
        callback && callback();
        console.error(err);
      });
  };

  onClickTrigger = () => {
    if (this.props.useExtraMember === 'project' && !this.state.isMemberOverlayVisible) {
      this.getDataSource(() => {
        this.setState({
          isMemberOverlayVisible: !this.state.isMemberOverlayVisible,
        });
      });
    } else {
      this.setState({
        isMemberOverlayVisible: !this.state.isMemberOverlayVisible,
      });
    }
  };

  onVisibleChange = (visible) => {
    this.setState({
      isMemberOverlayVisible: !!visible,
    });
  };

  handleChange = (value) => {
    this.props.onChange(value);
    this.onVisibleChange(false);
  };

  deleteUser = (curUser) => {
    const { value } = this.props;
    const newValue = value.filter((item) => {
      return curUser._userId !== item._userId && item.tb_user_id !== curUser._userId;
    });
    this.props.onChange(newValue);
  };

  /**
   * @param {*} container 成员组件指定挂载的html节点
   * @param {*} triggerEle 成员组件指定的target或safeNode
   * @returns JSX或null
   */
  renderMemberDialog = (container, triggerEle) => {
    const { pathResourceId } = this.props;
    const { pathResource } = window.FORCE;
    const { memberSettingShow } = this.state;

    if (!memberSettingShow) {
      return null;
    }
    const memberContainer = container
      ? { container, target: () => triggerEle, safeNode: () => triggerEle }
      : {};
    return (
      <MemberList
        {...memberContainer}
        pathResourceId={pathResourceId || pathResource.id}
        pathResourceType="project"
        align="tr br"
        role={pathResource.role}
        visible={memberSettingShow}
        autoOpenAddPanel
        onClose={() => {
          this.setState({
            memberSettingShow: false,
          });

          if (this.props.useExtraMember === 'project') {
            this.getDataSource();
          }
        }}
      />
    );
  };

  render() {
    const {
      value,
      container,
      followTrigger,
      align,
      needAvatar,
      mode,
      defaultList,
      multiple,
      useExtraMember,
      useRecommendMember,
      recommendList,
      useProjectMember,
      noMore,
      ...others
    } = this.props;
    const { orgMembers, isMemberOverlayVisible, extraMembers } = this.state;
    let useDataSource = useExtraMember && extraMembers && extraMembers.length;
    // 处理DataSource数据格式
    let ds = [];
    if (useDataSource) {
      ds = extraMembers.map((item) => {
        item.userInfo = {};
        item._userId = item.tb_user_id;
        item.userInfo.avatarUrl = item.avatar_url;
        item.userInfo.name = item.name;
        return item;
      });
    }
    if (useRecommendMember) {
      ds = recommendList.map((item) => {
        item.userInfo = {};
        item._userId = item.tb_user_id;
        item.userInfo.avatarUrl = item.avatar_url;
        item.userInfo.name = item.name;
        return item;
      });
    }

    // 数据格式不一致，处理为一致
    const dataSource = value.map((item) => {
      item._userId = item._userId || item.tb_user_id;
      switch (item.status) {
        case 'approved':
          item.statusText = intl.get({
            id: 'code-assets.components.memberTrigger.Passed',
            defaultMessage: '已通过',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker commented">
              <img src="https://img.alicdn.com/tfs/TB1.4QPii_1gK0jSZFqXXcpaXXa-24-24.png" alt="" />
            </div>
          );

          break;
        case 'comment':
          item.statusText = intl.get({
            id: 'code-assets.components.memberTrigger.Commented',
            defaultMessage: '已评论',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker reviewed">
              <img src="https://img.alicdn.com/tfs/TB1THZNieL2gK0jSZPhXXahvXXa-24-24.png" alt="" />
            </div>
          );

          break;
        case 'pending':
          item.statusText = intl.get({
            id: 'code-assets.components.memberTrigger.Failed',
            defaultMessage: '未通过',
          });
          item.marker = (
            <div className="mr-overview-avatar-marker not-reviewed">
              <img src="https://img.alicdn.com/tfs/TB1kVgRihv1gK0jSZFFXXb0sXXa-24-24.png" alt="" />
            </div>
          );

          break;
        default:
          item.statusText = '';
          item.marker = null;
      }

      if (useDataSource) {
        // 查看当前评审者是否是库成员
        let isProjectMember = false;
        ds.forEach((m) => {
          if (m._userId === item._userId) {
            isProjectMember = true;
          }
        });

        // 不是库成员，加到Member的数据源中
        if (isProjectMember === false) {
          const u = {};
          u.avatar_url = item.avatar_url;
          u.id = item.id;
          u.name = item.name;
          u.state = item.state;
          u._userId = item._userId;
          u.username = item.username;
          u.userInfo = {};
          u.userInfo.avatarUrl = item.avatar_url;
          u.userInfo.name = item.name;
          u.score = 0;
          ds.push(u);
        }
      }

      return item;
    });

    if (useProjectMember) {
      useDataSource = true;
    }

    if (useRecommendMember) {
      ds = ds.sort((a, b) => {
        return b.score - a.score;
      });
      ds = ds.map((item, index) => {
        if (index < 3) {
          item.tag = {
            color: 'blue',
            children: intl.get({
              id: 'code-assets.components.memberTrigger.Recommended',
              defaultMessage: '推荐',
            }),
          };
        }
        return item;
      });
    }

    const trigger =
      dataSource && dataSource.length > 0 ? (
        <div
          className={`member-trigger hasData ${needAvatar ? 'needAvatar' : ''}`}
          ref={(o) => {
            this.triggerEle = o;
          }}
        >
          <span>
            <ClusterAvatar
              dataSource={dataSource.map((item) => {
                return {
                  ...item,
                  img:
                    item.avatar_url ||
                    (item.userInfo && item.userInfo.avatarUrl) ||
                    item.avatar ||
                    '',
                  text: item.name,
                };
              })}
              onAdd={this.onClickTrigger}
              onClose={this.deleteUser}
            />
          </span>
        </div>
      ) : (
        <div
          className="member-trigger wait"
          onClick={this.onClickTrigger}
          ref={(o) => {
            this.triggerEle = o;
          }}
        >
          <YunxiaoIcon type="add-members-line" />
          {intl.get({
            id: 'code-assets.components.memberTrigger.ToBeSelected',
            defaultMessage: '待选择',
          })}
        </div>
      );
    return (
      <React.Fragment>
        {this.props.trigger
          ? React.cloneElement(this.props.trigger, {
              onClick: (e) => {
                this.props.trigger.props.onClick && this.props.trigger.props.onClick(e);
                this.onClickTrigger();
              },
              ref: (o) => {
                this.triggerEle = o;
              },
            })
          : trigger}
        <Member
          {...others}
          container={container}
          trigger={<span />}
          target={() => this.triggerEle}
          visible={isMemberOverlayVisible}
          type="mini"
          autoFocus
          onRequestClose={this.onVisibleChange}
          multiple={multiple}
          onChange={this.handleChange}
          safeNode={() => this.triggerEle}
          align={align}
          value={dataSource}
          dataSource={useDataSource ? ds.filter((v) => v.member_type !== 'TEAMS') : null}
          followTrigger={followTrigger}
          mode={mode}
          defaultList={defaultList || 'default'}
          inviteBtn={getFeature('member.memberList.inviteBtn') && !noMore && orgMembers.length < 5}
          inviteBtnClick={() => {
            if (this.props.isInviteUrl) {
              const { organization_id } = window.FORCE.organization;
              // 临时方案，等底座后端邀请链接重构后即可去掉
              const nextUrl = encodeURIComponent(`${location.origin}?org_id=${organization_id}`);
              const inviteUrl = `https://devops.aliyun.com/org-admin/${organization_id}/members/member?invite=true&next_url=${nextUrl}`;
              navigateOpen(inviteUrl, '_blank');
            } else {
              this.setState({
                memberSettingShow: true,
              });
            }
          }}
          customSearchAll={getFeature('member.customSearchAll') ? customMemberSearchAll : undefined}
        />

        {this.renderMemberDialog(container, this.triggerEle)}
      </React.Fragment>
    );
  }
}
